#include "ImageThumbsCache.h"
#include <assert.h>
#include <QtCore/QFileInfo>
#include <QtCore/QDir>
#include "Utility.h"
#include <QtCore/QDebug>

#define QSEE_THUMBS_FILE_NAME "Thumbs.QSee.dll"
#define QSEE_DEFAULT_THUMBS_SIZE 70
#define QSEE_THUMBS_FILE_HEADER "QSeeThumbs Ver 1.00             "


ImageThumbsCache::ImageThumbsCache()
:QObject(),_thumbsSize(QSEE_DEFAULT_THUMBS_SIZE,QSEE_DEFAULT_THUMBS_SIZE)
{
	connect (&_imageLoader,SIGNAL(imageLoaded(const QImage& ,const QString& )),
				this,SLOT(onImageLoaded(const QImage& ,const QString&)));

	_isModified=true;
}

ImageThumbsCache::~ImageThumbsCache()
{

}

void ImageThumbsCache::setThumbsSize(const QSize& size) {
	if (_thumbsSize!=size){
		_thumbsSize=size;
		startRefreshing();
	}
}


void ImageThumbsCache::onImageLoaded(const QImage& image,const QString& filePath){
	QString fileName=QFileInfo(filePath).fileName();
	ImageFileThumb* thumb=findThumb(fileName);
	if (thumb){
		thumb->setThumbImage(image);
		_isModified=true;
		emit imageChanged(fileName);
	}
}

void ImageThumbsCache::load(const QString& absDirPath){
	if (_currAbsDirPath==absDirPath)
		return;

	this->clear();
	_currAbsDirPath=absDirPath;
	_isModified=false;
	QFile thumbsFile(absDirPath+"/"QSEE_THUMBS_FILE_NAME);
	if (!thumbsFile.exists()){
		return ;
	}

	if (!thumbsFile.open(QIODevice::ReadOnly)){
		qDebug()<<"Open file "<<absDirPath+"/"QSEE_THUMBS_FILE_NAME<<" failed!\n";
		return ;
	}
			
	QDataStream dataStream(&thumbsFile);
	QString head;
	dataStream>>head;
	if (head!=QSEE_THUMBS_FILE_HEADER){
		qDebug()<<"Unknown thumbs header :"<<head<<"\n";
		return ;
	}
	int thumbsCount=0;
	dataStream>>thumbsCount;
	for(int i=0;i<thumbsCount;++i){
		ImageFileThumb* thumb=new ImageFileThumb(absDirPath);
		dataStream>>(*thumb);
		_imageFileThumbs.insert(thumb->fileName(),thumb);
	}

	thumbsFile.close();
}

void ImageThumbsCache::save() const{
	assert(!_currAbsDirPath.isEmpty());
	if (_currAbsDirPath.isEmpty())
		return;

	if (_isModified){
		QFile thumbsFile(_currAbsDirPath+"/"+QSEE_THUMBS_FILE_NAME);
		if (!thumbsFile.open(QIODevice::WriteOnly)){
			return ;
		}
		QDataStream dataStream(&thumbsFile);
		dataStream<<QString(QSEE_THUMBS_FILE_HEADER);
		dataStream<<_imageFileThumbs.size();
		foreach(ImageFileThumb* thumb,_imageFileThumbs){
			if (thumb->isValid()){
				dataStream<<(*thumb);
			}
		}

		thumbsFile.close();
		_isModified=false;
	}
}

ImageFileThumb*  ImageThumbsCache::findThumb(const QString& fileName) {
	ImageFileThumbs::const_iterator i=_imageFileThumbs.find(fileName);
	if (i!=_imageFileThumbs.end()){
		if ((*i)->isValid()){
			return (*i);
		}else{
			_imageFileThumbs.remove(fileName);
			delete (*i);
		}
	}
	return 0;
}

ImageFileThumb*  ImageThumbsCache::createThumb(const QString& fileName,const QSize& size){
	ImageFileThumb* thumb=new ImageFileThumb(_currAbsDirPath);
	thumb->setFileName(fileName);
	_imageFileThumbs.insert(thumb->fileName(),thumb);
	_imageLoader.startLoad(_currAbsDirPath+"/"+fileName,size);
	return thumb;
}

void ImageThumbsCache::clear(){
	qDeleteAll(_imageFileThumbs.begin(),_imageFileThumbs.end());
	_imageFileThumbs.clear();
	_isModified=true;
}

QImage ImageThumbsCache::image(const QString& fileName) {
	QString absFilePath=_currAbsDirPath+"/"+fileName;
	ImageFileThumb*  thumb=findThumb(fileName);
	if (thumb){
		if (thumb->isDirty()){
			assert(QFile::exists(absFilePath));
			_imageLoader.startLoad(absFilePath,_thumbsSize);
		}
		return thumb->image();
	}else if (QFile::exists(absFilePath)){
		return createThumb(fileName,_thumbsSize)->image();
	}else{
		return QImage();
	}
}

void ImageThumbsCache::notifyFileRenamed(const QString& name,const QString& newName){
	QString newFileName=QFileInfo(newName).fileName();
	ImageFileThumbs::const_iterator i=_imageFileThumbs.find(QFileInfo(name).fileName());
	if (i!=_imageFileThumbs.end()){
		(*i)->renameFile(newFileName);
	}else{
		image(newFileName);
	}
}

void ImageThumbsCache::startRefreshing(){
	foreach (const QString& file,QDir(_currAbsDirPath).entryList(Utility::getImageFileFilters(),QDir::Files)){
		image(file);
	}
}

void ImageThumbsCache::stopRefreshing(){
	
}
